// joint.cpp
#include "joint.h"
#include <QVBoxLayout>
#include <QSizePolicy>
#include <QDebug>

Joint::Joint(const QString &jointName, const QJsonObject &jointDetails, QWidget *parent)
    : QWidget(parent), m_jointName(jointName)
{
    setupControls(jointDetails);
    connectSignals();
}
/**********************************************
* @file       joint.cpp
* @brief      后续可以在这个函数中书写对应逻辑
* 例如通过操作按钮发出信号操控设备，或者订阅设备信息来显示当前状态
* 通过 槽函数 信号机制
* @author     yfk
* @date       2024-12-10
**********************************************/

// void Joint::setupControls(const QJsonObject &jointDetails)
// {
// //    QString minStr = jointDetails["min"].toString();
// //    QString maxStr = jointDetails["max"].toString();
// //    QString defStr = jointDetails["default"].toString();

// //    m_min = minStr.toInt();
// //    m_max = maxStr.toInt();
// //    m_default = defStr.toInt();
//     m_min = jointDetails["min"].toInt();
//     m_max = jointDetails["max"].toInt();
//     m_default = jointDetails["default"].toInt();

//     qDebug()<< "min  " << m_min << "max "<< m_max << "m_default " << m_default;
//     if (m_min == 0 || m_max == 0) {
//         qWarning() << "Invalid range for joint " << m_jointName;
//         qDebug() << "测试";
//     }

//     // 创建栅格布局
//     QGridLayout *gridLayout = new QGridLayout(this);

//     // 创建控件
//     QLabel *jointLabel = new QLabel(m_jointName, this);
//     decreaseButton = new QPushButton("-", this);  // 初始化按钮
//     increaseButton = new QPushButton("+", this);  // 初始化按钮
//     m_slider = new QSlider(Qt::Horizontal, this);
//     m_angleDisplay = new QLineEdit(this);
//     QLabel *degreeLabel = new QLabel("degrees", this);

//     // 设置滑块的范围与默认值
//     m_slider->setRange(m_min, m_max);
//     m_slider->setValue(m_default);
//     m_angleDisplay->setText(QString::number(m_slider->value()));

//     // 将控件添加到栅格布局
//     gridLayout->addWidget(jointLabel, 0, 0);
//     gridLayout->addWidget(decreaseButton, 0, 1);
//     gridLayout->addWidget(m_slider, 0, 2);
//     gridLayout->addWidget(increaseButton, 0, 3);
//     gridLayout->addWidget(m_angleDisplay, 0, 4);
//     gridLayout->addWidget(degreeLabel, 0, 5);

//     this->setLayout(gridLayout);
// }
void Joint::setupControls(const QJsonObject &jointDetails)
{
    m_min = jointDetails["min"].toDouble() * 100;  // 将min乘以100
    m_max = jointDetails["max"].toDouble() * 100;  // 将max乘以100
    m_default = jointDetails["DefaultValue"].toDouble() * 100;  // 将default乘以100

    qDebug()<< "min  " << m_min << "max "<< m_max << "m_default " << m_default;
    if (m_min == 0 || m_max == 0) {
        qWarning() << "Invalid range for joint " << m_jointName;
        // qDebug() << "测试";
    }

    // 创建栅格布局
    QHBoxLayout *hBoxLayout = new QHBoxLayout(this);
    hBoxLayout->setContentsMargins(0, 0, 0, 0);  // 去除外部边距
    // 创建控件
    QLabel *jointLabel = new QLabel(m_jointName, this);
    decreaseButton = new QPushButton("-", this);  // 初始化按钮
    increaseButton = new QPushButton("+", this);  // 初始化按钮
    m_slider = new QSlider(Qt::Horizontal, this);
    m_angleDisplay = new QLineEdit(this);
    QLabel *degreeLabel = new QLabel("degrees", this);

    // 设置滑块的范围与默认值
    m_slider->setRange(m_min, m_max);
    qDebug() << "m_slider->setValue(m_default);" << m_default << Qt::endl;
    m_slider->setValue(m_default);
    m_slider->setMinimumSize(120, 20);  // 设置滑块的最小宽度
    m_angleDisplay->setText(QString::number(m_default / 100.0, 'f', 2));  // 显示小数
    qDebug() << " m_angleDisplay" << m_default / 100.0 << Qt::endl;


    // 设置按钮和 QLineEdit 的扩展策略
    decreaseButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);  // 水平扩展，垂直不扩展
    increaseButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);  // 水平扩展，垂直不扩展
    m_angleDisplay->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);  // 水平扩展，垂直不扩展

    // 设置输入框字体大小
    QFont inputFont = m_angleDisplay->font();
    inputFont.setPointSize(10);  // 设置字体大小
    m_angleDisplay->setFont(inputFont);
    // m_angleDisplay->setReadOnly(true);  // 设置为只读，不能编辑
    m_angleDisplay->setAlignment(Qt::AlignCenter);  // 将文本居中对齐


    // 设置按钮和角度显示框的最小和最大尺寸
    decreaseButton->setMinimumSize(60, 15);  // 最小尺寸
    decreaseButton->setMaximumSize(80, 40);  // 最大尺寸
    increaseButton->setMinimumSize(60, 15);  // 最小尺寸
    increaseButton->setMaximumSize(80, 40);  // 最大尺寸
    m_angleDisplay->setMinimumSize(60, 15);  // 最小尺寸
    m_angleDisplay->setMaximumSize(150, 40);  // 最大尺寸


    hBoxLayout->setContentsMargins(0, 0, 0, 0);  // 去除外部边距
    decreaseButton->setContentsMargins(0, 0, 0, 0);  // 去除按钮内部的边距
    increaseButton->setContentsMargins(0, 0, 0, 0);  // 去除按钮内部的边距
    m_angleDisplay->setContentsMargins(0, 0, 0, 0);  // 去除输入框内部的边距
    // 在 jointLabel 和 m_angleDisplay 前后加上弹簧

    // 设置 QValidator（可选）：确保输入值是有效的数字
    // QIntValidator *validator = new QIntValidator(m_min, m_max, this);  // 限制输入范围为 min 和 max
    // m_angleDisplay->setValidator(validator);

    QSpacerItem *Spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

    // 将控件添加到布局
    hBoxLayout->addWidget(jointLabel);
    // hBoxLayout->addItem(Spacer);  // 左侧弹簧
    hBoxLayout->addWidget(decreaseButton);
    hBoxLayout->addWidget(m_slider);
    hBoxLayout->addWidget(increaseButton);
    // hBoxLayout->addItem(Spacer);  // 左侧弹簧
    hBoxLayout->addWidget(m_angleDisplay);
    // hBoxLayout->addItem(Spacer);  // 左侧弹簧
    hBoxLayout->addWidget(degreeLabel);



    this->setLayout(hBoxLayout);
    // qDebug() << "decreaseButton size: " << decreaseButton->size();
    // qDebug() << "decreaseButton width: " << decreaseButton->width();
    // qDebug() << "decreaseButton height: " << decreaseButton->height();
}

void Joint::connectSignals()
{
    // 更新角度显示并同步滑块值
    connect(m_slider, &QSlider::valueChanged, m_angleDisplay, [=](double value) {
        double doubleValue = (static_cast<double>(value)) / 100.0;  // 显示为小数
        m_angleDisplay->setText(QString::number(doubleValue, 'f', 2));  // 显示为小数
        emit angleChanged(m_jointName, doubleValue);  // 发出角度改变信号，传递 double 类型值
    });

    // 按钮控制滑块值
    connect(decreaseButton, &QPushButton::clicked, [=]() {
        int value = m_slider->value();
        m_slider->setValue(value - 1);  // 降低角度
    });

    connect(increaseButton, &QPushButton::clicked, [=]() {
        int value = m_slider->value();
        m_slider->setValue(value + 1);  // 增加角度
    });

    // 当输入框的编辑完成时，处理值并同步
    connect(m_angleDisplay, &QLineEdit::editingFinished, [=]() {
        bool ok;
        QString inputText = m_angleDisplay->text();
        double value = inputText.toDouble(&ok); // 将输入框中的值转换为 double 类型

        if (ok) {
            // 检查值是否在范围内
            if (value >= m_min / 100.0 && value <= m_max / 100.0) {
                int intValue = static_cast<int>(value * 100);  // 将 double 转换为整数以更新滑块
                m_slider->setValue(intValue);  // 设置滑块的值
                // emit angleChanged(m_jointName, value);  // 发出角度改变信号，传递 double 类型的值
            } else {
                qWarning() << "Input value " << value << " is out of range!";
                m_angleDisplay->setText(QString::number(m_slider->value() / 100.0, 'f', 2));  // 恢复显示当前值
                QMessageBox::warning(this, "Invalid Input",
                                     QString("Please enter a value between %1 and %2.")
                                         .arg(m_min / 100.0).arg(m_max / 100.0));
            }
        } else {
            qWarning() << "Invalid input: " << inputText;
            m_angleDisplay->setText(QString::number(m_slider->value() / 100.0, 'f', 2));  // 恢复显示当前值
            QMessageBox::warning(this, "Invalid Input",
                                 QString("Please enter a valid number between %1 and %2.")
                                     .arg(m_min / 100.0).arg(m_max / 100.0));
        }
    });
}

QWidget* Joint::getWidget()
{
    return this;  // 返回自己作为控件
}

void Joint::reset()
{
    // 将滑块值重置为默认值
    m_slider->setValue(m_default);
    qDebug() << QString::number(m_default / 100.0, 'f', 2) << Qt::endl;

    // 更新角度显示
    m_angleDisplay->setText(QString::number(m_default / 100.0, 'f', 2));
}

void Joint::reset(QString name)
{
    // 将滑块值重置为默认值
    m_slider->setValue(m_default);
    qDebug() <<"joint 中 "<< QString::number(m_default / 100.0, 'f', 2) << Qt::endl;
    emit angleChanged(name, m_default / 100.0);  // 发出角度改变信号，传递 double 类型值
   qDebug() <<"joint 中  emit angleChanged(name, m_default);" << Qt::endl;

    // 更新角度显示
    m_angleDisplay->setText(QString::number(m_default / 100.0, 'f', 2));

}

// 在 Joint 类中添加一个 getter 方法来访问 QLineEdit
QLineEdit* Joint::getAngleDisplay()
{
    return m_angleDisplay;
}

// 在 Joint 类中添加一个 getter 方法来访问关节的名称
QString Joint::getJointName()
{
    return m_jointName;
}


